package AdminClient;

import static AdminClient.Debug.debug;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Vector;
import java.util.*;

//Note: if you want to access the actual lists here, use the capitalized
//getters and setters at the bottom
//Ex: using getPlayer as opposed to get_player
//though either one should give you the same thing
//the other one just gets it directly from the server
public class AdminInfo {
	
	ServerInterface server_interface;
	AdminGUI gui; ////////////////////NEW
	Queue<String> updates = new LinkedList<String>(); /////////////////
	private String name;
	private ObjectList<Room> rooms;
	private ObjectList<Player> players;
	public boolean done = false;
	private ObjectList<Item> items;
	public static final String delimiter = "|";
	private String hostname="CYWZBD1";
	private int cport=8901;
	private int uport=8902;
	
	public AdminInfo()
	{
		//////////////////////////////////////new
		run_updates_thread run_updates = new run_updates_thread();
		run_updates.start();
		//////////////////////////////////////new
	}

	public void set_server(ServerInterface s)
	{
		server_interface = s;
	}
	
	public void set_gui(AdminGUI g) /////////////////////NEW
	{
		gui = g;
	}
	
	public String[] send_message(String msg)
	{
		System.out.println("sending message"+msg);
		String ret_msg = server_interface.admin_thread.send_message(msg);
		System.out.println("Received Message: " + ret_msg + " from server");
		String msg_split[] = ret_msg.split("\\" + delimiter);
		return msg_split;
	}
	
	////////////////////////////////////////////new
	public void send_update(String msg)
	{
		updates.add(msg);
	}
	/////////////////////////////////////////////new
	
	/////////////////////////////////////////////new
	private class run_updates_thread extends Thread
	{
		public void run()
		{
			while(!done)
			{
				try{
					sleep(100);
				} catch (InterruptedException e)
				{
					System.out.println("Update Thread Interrupt");
				}
				while(!updates.isEmpty())
				{
					try{
						sleep(100);
					} catch (InterruptedException e)
					{
						System.out.println("Update Thread Interrupt");
					}
					//System.out.print("UPDATER: ");
					String s = updates.remove();
					update(s);
					//System.out.println(s);
				}
			}
		}
	}
	/////////////////////////////////////////////new
	public void update(String msg)
	{
		//String[] message=Msg_Pipe.parse_message(msg);
		//String type=message[0];
		/*
		if(type.equals(""))
		{
			
		}
		else if (type.equals("room_added"))
		{
			this.roomAdded(message);
		}
		//might change
		else if (type.equals("add_item"))
		{
			this.itemAdded(message);
		}
		else if (type.equals("player_added"))
		{
			this.playerAdded(message);
		}
		else if (type.equals("item_arrived"))
		{
			this.itemArrived(message);
		}
		else if (type.equals("item_gone"))
		{
			this.itemGone(message);
		}
		else if (type.equals("item_locked"))
		{
			this.itemLocked(message);
		}
		else if (type.equals("item_unlocked"))
		{
			this.itemUnlocked(message);
		}
		//not done
		else if (type.equals("move"))
		{
			
		}
		else if (type.equals("player_removed"))
		{
			this.playerRemoved(message);
		}
		else if (type.equals("item_removed"))
		{
			this.itemRemoved(message);
		}
		else if (type.equals("room_removed"))
		{
			this.roomRemoved(message);
		}
		else if (type.equals("item_modified"))
		{
			this.itemModified(message);
		}
		else if (type.equals("room_modified"))
		{
			this.roomModified(message);
		}
		else if (type.equals("player_modified"))
		{
			this.itemArrived(message);
		}
		else if (type.equals("player_arrived"))
		{
			this.itemArrived(message);
		}
		else if (type.equals("player_departed"))
		{
			this.itemArrived(message);
		}
		else
			return;
			//invalid message
			 * 
			 */
		gui.updateGUI();
		
	}
	public void get_server()
	{
		String msg="get_server";
		String[] ret= send_message(msg);
		if(ret.length==4)
		{
				hostname = ret[1];
				cport=Integer.parseInt(ret[2]);
				uport=Integer.parseInt(ret[3]);
		}
	}
	public void logoff()
	{
		done=true;
	}
	public boolean shutdown()
	{
		//done=true;
		String msg="shutdown";
		String[]ret= send_message(msg);
		if (ret.length==0)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
		{
			done=true;
			return true;
		}
		return false;
	}
	public boolean add_room(String name, String description) {
	String msg="add_room"+delimiter+name+delimiter+description;
	String[] ret= send_message(msg);
	if (ret.length==0)
		return false;
	if(ret[0].equals(Msg_Pipe.success))
		return true;
	return false;
	}
	
	public boolean add_local_portal(String room, String to_room) {
		String msg="add_portal"+delimiter+room+delimiter+to_room+
			delimiter+hostname+delimiter+cport+delimiter+uport+delimiter+true;
		String[] ret= send_message(msg);
		if (ret.length==0)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	public boolean add_server_portal(String room, String to_room,
			String hostname, int cport, int uport) {
		String msg="add_portal"+delimiter+room+delimiter+to_room+delimiter+
		hostname+delimiter+cport+delimiter+uport+false;
		String[] ret= send_message(msg);
		if (ret.length==0)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	
	public boolean add_item(String name, String room, String description) {
		String msg="add_item"+delimiter+name+delimiter+room+delimiter+description;
		String[] ret= send_message(msg);
		if (ret.length!=1)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	public String[] get_portals(String room)
	{
		String msg="get_portals"+delimiter+room;
		String[] ret;
		String[] returned= send_message(msg);
		if(returned[0]==Msg_Pipe.failure)
		return ret=new String[0];
		else
		{
			ret=new String[returned.length-1];
			for(int i=1; i<returned.length; i++)
				ret[i-1]=returned[i];
		}
		return ret;
	}
	public String[] get_room_items(String room)
	{
		String msg="get_room_items"+delimiter+room;
		String[] ret;
		String[] returned= send_message(msg);
		if(returned[0]==Msg_Pipe.failure)
		return null;
		else
		{
			ret=new String[returned.length-1];
			for(int i=1; i<returned.length; i++)
				ret[i-1]=returned[i];
		}
		return ret;
	}
	public String[] get_player_items(String room)
	{
		String msg="get_room_items"+delimiter+room;
		String[] ret;
		String[] returned= send_message(msg);
		if(returned[0]==Msg_Pipe.failure)
		return null;
		else
		{
			ret=new String[returned.length-1];
			for(int i=1; i<returned.length; i++)
				ret[i-1]=returned[i];
		}
		return ret;
	}
	public Item get_item(String item)
	{
		String msg="get_item"+delimiter+item;
		Item i;
		String[] returned= send_message(msg);
		if(returned.length!=4||returned[0]==Msg_Pipe.failure)
		return null;
		else
		{
			i=new Item(returned[1], returned[2], returned[3]);
		}
		return i;
	}
	public boolean lock_item(String item)
	{
		String msg="lock_item"+delimiter+item;
		String[] returned = send_message(msg);
		if(returned.length!=1||returned[0]==Msg_Pipe.failure)
			return false;
		return true;
	}
	public boolean unlock_item(String item)
	{
		String msg="unlock_item"+delimiter+item;
		String[] returned= send_message(msg);
		if(returned.length!=1||returned[0]==Msg_Pipe.failure)
			return false;
		return true;
	}
	public String[] get_players()
	{
		String msg="get_players";
		String[] ret;
		String[] returned= send_message(msg);
		if(returned[0]==Msg_Pipe.failure)
		return null;
		else
		{
			ret=new String[returned.length-1];
			for(int i=1; i<returned.length; i++)
				ret[i-1]=returned[i];
		}
		return ret;
	}
	public String[] get_room_players(String room)
	{
		String msg="get_room_players"+delimiter+room;
		String[] ret;
		String[] returned= send_message(msg);
		if(returned[0]==Msg_Pipe.failure)
		return null;
		else
		{
			ret=new String[returned.length-1];
			for(int i=1; i<returned.length; i++)
				ret[i-1]=returned[i];
		}
		return ret;
	}
	public String get_current_room(String player)
	{
		String msg="get_current_room"+delimiter+player;
		String[] returned= send_message(msg);
		if(returned.length!=2||returned[0]==Msg_Pipe.failure)
			return null;
		return returned[1];
	}
	public String[] get_rooms()
	{
		String msg="get_rooms";
		String[] ret;
		String[] returned= send_message(msg);
		if(returned[0]==Msg_Pipe.failure)
		return null;
		else
		{
			ret=new String[returned.length-1];
			for(int i=1; i<returned.length; i++)
				ret[i-1]=returned[i];
		}
		return ret;
	}
	//check orders
	public Player get_player(String player)
	{
		String msg="get_player"+delimiter+player;
		String[] returned= send_message(msg);
		if(returned.length!=5)
			return null;
		Player p=new Player(returned[1], returned[2], returned[3]);
		p.set_active(Boolean.parseBoolean(returned[4]));
		return p;
	}
	public Room get_room(String room)
	{
		String msg="get_room"+delimiter+room;
		String[] returned= send_message(msg);
		if(returned.length!=3)
			return null;
		Room r=new Room(returned[1], returned[2]);
		return r;
	}
	public String[] get_items()
	{
		String msg="get_items";
		String[] ret;
		String[] returned= send_message(msg);
		if(returned[0]==Msg_Pipe.failure)
		return null;
		else
		{
			ret=new String[returned.length-1];
			for(int i=1; i<returned.length; i++)
				ret[i-1]=returned[i];
		}
		return ret;
	}
	public boolean remove_player(String player) {
		String msg="remove_player"+delimiter+player;
		String[] ret= send_message(msg);
		if (ret.length!=1)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	public boolean remove_item(String item) {
		String msg="remove_item"+delimiter+item;
		String[] ret= send_message(msg);
		if (ret.length!=1)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	public boolean remove_room(String room) {
		String msg="remove_room"+delimiter+room;
		String[] ret= send_message(msg);
		if (ret.length!=1)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	public boolean remove_portal(String room, String to_room) {
		String msg="remove_portal"+delimiter+room+delimiter+to_room;
		String[] ret= send_message(msg);
		if (ret.length!=1)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	public boolean modify_item(String name, String new_name, String description) {
		String msg="modify_item"+delimiter+name+delimiter+new_name+delimiter+description;
		String[] ret= send_message(msg);
		if (ret.length!=1)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	public boolean modify_room(String name, String new_name, String description) {
		String msg="modify_room"+delimiter+name+delimiter+new_name+delimiter+description;
		String[] ret= send_message(msg);
		if (ret.length!=1)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	public boolean modify_player(String name, String new_name) {
		String msg="modify_item"+delimiter+name+delimiter+new_name;
		String[] ret= send_message(msg);
		if (ret.length!=1)
			return false;
		if(ret[0].equals(Msg_Pipe.success))
			return true;
		return false;
		}
	public void generate_item_list()
	{
		String[] item_names=get_items();
		ObjectList<Item> item_list=new ObjectList<Item>();
		for(int i=0; i<item_names.length; i++)
		{
			item_list.add(get_item(item_names[i]));
		}
		items=item_list;
	}
	public void generate_player_list()
	{
		String[] player_names=get_players();
		ObjectList<Player> player_list=new ObjectList<Player>();
		for(int i=0; i<player_names.length; i++)
		{
			player_list.add(get_player(player_names[i]));
		}
		players=player_list;
	}
	//doesn't actually generate portals
	public void generate_room_list()
	{
		String[] room_names=get_rooms();
		ObjectList<Room> room_list=new ObjectList<Room>();
		for(int i=0; i<room_names.length; i++)
		{
			room_list.add(get_room(room_names[i]));
		}
		rooms=room_list;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public ObjectList<Room> getRooms() {
		return rooms;
	}

	public void setRooms(ObjectList<Room> rooms) {
		this.rooms = rooms;
	}

	public ObjectList<Player> getPlayers() {
		return players;
	}
	public ObjectList<Player> getActivePlayers()
	{
		ObjectList<Player> playerList= new ObjectList<Player>();
		for(int i=0; i<players.size(); i++)
		{
			if(players.get(i).get_active())
				playerList.add(players.get(i));
		}
		return playerList;
	}
	public void setPlayers(ObjectList<Player> players) {
		this.players = players;
	}

	public ObjectList<Item> getItems() {
		return items;
	}

	public void setItems(ObjectList<Item> items) {
		this.items = items;
	}
	public Player getPlayer(String player)
	{
		for(int i=0; i<players.size(); i++)
		{
			if(players.get(i).get_name()==player)
				return players.get(i);
		}
		return null;
	}
	public Room getRoom(String room)
	{
		for(int i=0; i<rooms.size(); i++)
		{
			if(rooms.get(i).get_name()==room)
				return rooms.get(i);
		}
		return null;
	}
	public Item getItem(String item)
	{
		for(int i=0; i<items.size(); i++)
		{
			if(items.get(i).get_name()==item)
				return items.get(i);
		}
		return null;
	}
	//update methods
	public void roomAdded(String[] body)
	{
		rooms.add(new Room(body[1], body[2]));
	}
	public void playerAdded(String[] body)
	{
		players.add(new Player(body[1], body[2], ""));
	}
	public void itemAdded(String[] body)
	{
		items.add(new Item(body[1], body[2], body[3]));
	}
	//portal added
	public void roomRemoved(String[] body)
	{
		Room r=getRoom(body[1]);
		rooms.remove(r);
		generate_item_list();
		//might be slow
	}
	public void playerRemoved(String[] body)
	{
		Player p=getPlayer(body[1]);
		players.remove(p);
		generate_item_list();
		//might be slow
	}
	public void itemRemoved(String[] body)
	{
		Item i=getItem(body[1]);
		items.remove(i);
	}
	//portal removed
	public void itemArrived(String[] body)
	{
		Item i=getItem(body[2]);
		i.set_location(body[1]);
	}
	public void itemGone(String[] body)
	{
		Item i=getItem(body[2]);
		i.set_location(body[3]);
	}
	public void itemLocked(String[] body)
	{
		Item i=getItem(body[2]);
		i.lock(true);
	}
	public void itemUnlocked(String[] body)
	{
		Item i=getItem(body[2]);
		i.lock(false);
	}
	//Ugly, but it'll work. Two different scenarios for arrival
	public void playerArrived(String[] body)
	{
		generate_player_list();
	}
	//ugly, but no better way because of limited update info and see above
	public void playerDeparted(String[] body)
	{
		generate_player_list();
	}
	public void itemModified(String[] body)
	{
		Item i=getItem(body[body.length-1]);
		i=this.get_item(body[1]);
		
	}
	public void roomModified(String[] body)
	{
		Room r=getRoom(body[body.length-1]);
		r=this.get_room(body[1]);
	}
	public void playerModified(String[] body)
	{
		Player p=getPlayer(body[body.length-1]);
		p=this.get_player(body[1]);
	}
}
